<html>
<body>
This inspection reports stream API call chains which can be simplified.
It allows to avoid creating redundant temporary objects when traversing a collection.
<p>
  The following call chains are replaced by this inspection:
</p>
<ul>
  <li><code>collection.stream().forEach()</code> &rarr; <code>collection.forEach()</code></li>
  <li><code>collection.stream().collect(toList/toSet/toCollection())</code> &rarr; <code>new CollectionType&lt;&gt;(collection)</code></li>
  <li><code>collection.stream().toArray()</code> &rarr; <code>collection.toArray()</code></li>
  <li><code>Arrays.asList().stream()</code> &rarr; <code>Arrays.stream()</code> or <code>Stream.of()</code></li>
  <li><code>IntStream.range(0, array.length).mapToObj(idx -> array[idx])</code> &rarr; <code>Arrays.stream(array)</code></li>
  <li><code>IntStream.range(0, list.size()).mapToObj(idx -> list.get(idx))</code> &rarr; <code>list.stream()</code></li>
  <li><code>Collections.singleton().stream()</code> &rarr; <code>Stream.of()</code></li>
  <li><code>Collections.emptyList().stream()</code> &rarr; <code>Stream.empty()</code></li>
  <li><code>stream.filter().findFirst().isPresent()</code> &rarr; <code>stream.anyMatch()</code></li>
  <li><code>stream.collect(counting())</code> &rarr; <code>stream.count()</code></li>
  <li><code>stream.collect(maxBy())</code> &rarr; <code>stream.max()</code></li>
  <li><code>stream.collect(mapping())</code> &rarr; <code>stream.map().collect()</code></li>
  <li><code>stream.collect(reducing())</code> &rarr; <code>stream.reduce()</code></li>
  <li><code>stream.collect(summingInt())</code> &rarr; <code>stream.mapToInt().sum()</code></li>
  <li><code>stream.mapToObj(x -> x)</code> &rarr; <code>stream.boxed()</code></li>
  <li><code>stream.map(x -> {...; return x;})</code> &rarr; <code>stream.peek(x -> ...)</code></li>
  <li><code>!stream.anyMatch()</code> &rarr; <code>stream.noneMatch()</code></li>
  <li><code>!stream.anyMatch(x -> !(...))</code> &rarr; <code>stream.allMatch()</code></li>
  <li><code>stream.map().anyMatch(Boolean::booleanValue)</code> -> <code>stream.anyMatch()</code></li>
</ul>
<p>
  Note that the replacements semantic may have minor difference in some cases.
  For example, <code>Collections.synchronizedList(...).stream().forEach()</code> is not
  synchronized while <code>Collections.synchronizedList(...).forEach()</code> is synchronized.
  Or <code>collect(Collectors.maxBy())</code> would return an empty <code>Optional</code> if the resulting
  element is <code>null</code> while <code>Stream.max()</code> will throw <code>NullPointerException</code>
  in this case.
</p>
</body>
</html>